package com.ezandroid.library.network.http.request;

import android.content.Context;
import android.text.TextUtils;

import okhttp3.OkHttpClient;

/**
 * a manager for {@link Request}.
 *
 * @author markmjw
 * @date 2015-05-29
 */
public class RequestManager {

    private static RequestManager sInstance;

    private Context mContext;

    private RequestQueue mRequestQueue;
    private HttpStackImpl mHttpStack;
    private Network mNetwork;

    private int mPoolSize = 5;

    public synchronized static RequestManager getInstance() {
        if (sInstance == null) {
            sInstance = new RequestManager();
        }
        return sInstance;
    }

    private RequestManager() {
    }

    /**
     * set pool size.
     *
     * @param size
     * @return
     */
    public RequestManager setPoolSize(int size) {
        if (size < 1 || size > 20) {
            throw new IllegalArgumentException("The pool size must be in 1~20");
        }
        mPoolSize = size;
        return this;
    }

    /**
     * set OkHttpClient for execute request.
     *
     * @param client
     * @return
     */
    public RequestManager setClient(OkHttpClient client) {
        mHttpStack = new HttpStackImpl(client);
        return this;
    }

    /**
     * get the default request queue
     *
     * @return default {@link RequestQueue}
     */
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            init(mContext);
        }
        return mRequestQueue;
    }

    /**
     * Get network.
     *
     * @return
     */
    public Network getNetwork() {
        if (null == mNetwork) {
            if (mHttpStack == null) {
                mHttpStack = new HttpStackImpl();
            }

            mNetwork = new NetworkImpl(mHttpStack);
        }

        return mNetwork;
    }

    /**
     * New a request queue.
     *
     * @return
     */
    public void init(Context context) {
        mContext = context.getApplicationContext();
        mRequestQueue = new RequestQueue(getNetwork(), mPoolSize);
        mRequestQueue.start();
    }

    /**
     * Cancel request by tag.
     *
     * @param tag
     */
    public void cancel(final Object tag) {
        if (null != mRequestQueue) {
            mRequestQueue.cancelAll(tag);
        }
    }

    /**
     * Cancel request by tag.
     *
     * @param tag
     */
    public void cancel(final String tag) {
        if (!TextUtils.isEmpty(tag)) {
            cancel(new RequestQueue.RequestFilter() {
                @Override
                public boolean apply(Request<?> request) {
                    return tag.equals(request.getTag());
                }
            });
        }
    }

    /**
     * Cancel request by RequestFilter.
     *
     * @param filter
     */
    public void cancel(RequestQueue.RequestFilter filter) {
        if (null != mRequestQueue) {
            mRequestQueue.cancelAll(filter);
        }
    }
}
